perm filename 2716.FAI[CMS,LCS] blob sn#473136 filedate 1979-09-10 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00016 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	Floppy disk directory routines.
C00005 00003	   LOC ZERO+200
C00007 00004	ITBL:	STAZ	3	IRQ vector. Save A
C00009 00005		CMPI	"T"	Type file
C00011 00006	DPYDSK:	LDAI	200	Setup disk buffer address
C00013 00007		LDAZ	SCNT	Number of sectors in directory
C00014 00008	OPIN:	JSR	LOKUP	Lookup file FNAM
C00015 00009	SETBUF:	LDAI	FBUF	Read disk into FBUF
C00017 00010	Create file routine
C00018 00011	WBUF:	JSR	SETBUF	Write FBUF
C00020 00012	CLOZE:	BITZ	WFOPEN	Check if file open
C00022 00013		LDAI	375	Point to header.
C00023 00014	Print a chr. on mem mapped dpy.
C00025 00015	Boot strap loader.
C00027 00016	TERM:	PLA	Fix stack
C00030 ENDMK
C⊗;
;Floppy disk directory routines.
.INSERT ASMBL.FAI[CMS,LCS]
.INSERT SYSDEF.FAI[CMS,LCS]

   LOC ZERO+21
CHR:	0	;Shifter temp. reg.
	0	;CUR
	0
SHFLOC:	0	;Shift lock bit
STOP:	JMP	STOP	;Go nowhere fast.
FLAD:	0	;Disk buffer pointer
	0
XU:	0	;Exec mode
WFOPEN:	0	;Write file open flag
OSEC:	0
FLEN:	0
UFLG:	0	;Program interrupt enable flag.
MFLG:	0	;Modem / SI/O flag.

   LOC ZERO+40
FBLK:	72	;File block
FNAM:	BLOCK 11	;9 Chr file name.
FTRK:	0	;Disk track number
FSEC:	0	;Disk sector number
NSEC:	0	;Number of sectors

   LOC ZERO+60
DBUF:	74	;Directory buffer
SCNT:	1	;Number of sectors
FCNT:	1	;Number of files
FFDIR:	20	;First free directory block
FFTRK:	376	;First free track
FFSEC:	376	;First free sector

   LOC ZERO+100
PCHRJ:	BLOCK 2	;Indirect print chr. jump.
   LOC ZERO+200
FBUF:		;Disk buffer

   LOC ZERO+1000	;Ram interrupt vectors.
IRQV:		;Maskable interrupt.
	BLOCK 5
NMIV:		;Non maskable interrupt.

   LOC ZERO+174000	;Start of 1k prom block.

;Power on reset.
STAR:	LDXI	377
	TXS	;Reset stack.

	LDAI	14	;Reset display
	STA	DPYRAS
	LDAI	377
	STA	DPYROW
	LDAI	120	;Default display control bits.
	STA	DPYCON
	LDAI	4
	STA	DPYMUX

	LDAI	PCHRR∧377	;Low byte of PCHR address.
	STAZ	PCHRJ	;Reset indirect PCHR jump.
	LDAI	(PCHRR⊗-10)∧377	;High byte.
	STAZ	PCHRJ+1

	LDAI	15
	STA	KBC
	STA	BRG0	;Baud rate generator.
	STA	BRG1
	LDXI	3	;Reset ACIA
	STX	ACIAC
	STA	ACIAC	;Control word

	LDXI	2
IDLMOV:	LDAX	IJMP	;Setup idle loop.
	STAZX	STOP
	DEX
	BPL	IDLMOV

	LDAI	200	;Setup display cursor
	STAZ	CURH

	LDAI	7	;CKB interrupt enable bits.
	STA	CRA	;Enable CKB interrupts.

	LDXI	17
RIVECT:	LDAX	ITBL	;Reset interrupt routines.
	STAX	IRQV
	DEX
	BPL	RIVECT

	INX	;X ← 0.
	STXZ	XU	;Reset Exec., and User flags.
	STXZ	UFLG

	STX	176376	;IRQ vector low.
	STX	176377	;Vector high.

	CLI
IJMP:	JMP	STOP

PJUMP:	JMP	PCHRR	;Default for indirect PCHR jump.
ITBL:	STAZ	3	;IRQ vector. Save A
	JMP	IPOLL

PNMIV:	PLA		;Non maskable interrupt vector
	PLA	;Flush stack
	PLA
	LDXI	0	;For ENDSK
	JSR	ENDSK	;Reset disk, timer. Read status
	JMP	RERR	;Return with error

IPOLL:	BIT	KBC	;Check if keyboard
	BMI	RKEY
	JMP	177432	;Jump to BDT

RKEY:	PHA	;Save registers
	TYA
	PHA
	TXA
	PHA
	LDA	KBD	;Read keyboard

	CMPI	352	;<Clear>
	BNE	CKX
	STAZ	XU	;Set exec.
	JSR	PCHR	;Echo it.
	JSR	CR	;<cr>
	LDAI	12	;<lf>
	STAZ	UFLG	;Disable program interrupts.
ECHO:	JSR	PCHR
	JMP	RTRN

   UMEM ← 1400	;Start of user memory.
CKX:	BITZ	XU	;Check mode
	BMI	EXEC
	BITZ	UFLG	;Check if program int.
	BPL	ECHO
	JMP	UMEM+10	;Jump to program.

EXEC:	CMPI	15	;<cr>
	BNE	ECHO
	JSR	PCHR	;Echo it
	LDYI	12	;Number of chrs+1 in FNAM
NLOOP:	LDAIY	CUR	;Save file name in FNAM
	STAY	37	;FBLK-1
	DEY
	BNE	NLOOP

	CMPI	40	;Check for <space>
	BEQ	GCMD
	LDAI	77	;"?"
	BNE	NOSPC

GCMD:	LDAIY	CUR	;Get command

NOSPC:	PHA
	LDAI	FMARK	;Setup file mark
	STAZ	FBLK
	JSR	LF	;Print <lf>.
	PLA
	CMPI	"T"	;Type file
	BNE	CKWRT

	JSR	OPIN
	BNE	XERR
	JSR	DPYDSK	;Setup disk load address
RIT:	JSR	READ	;Read the file
	JMP	ECK	;Check for error

CKWRT:	CMPI	"W"	;Save screen
	BNE	CKLOAD

	LDAI	20	;File length in sectors.
	JSR	ENTR
	BNE	XERR
	JSR	DPYDSK	;Setup disk write address
	BNE	WIT	;Write it

CKLOAD:	CMPI	"L"	;Load file
	BNE	CKRUN

	JSR	OPIN
	BNE	XERR
	JSR	ADRSET	;Setup disk read address
	BNE	RIT	;Jump and load it

CKRUN:	CMPI	"R"	;Run program
	BNE	CKUN

	JSR	OPIN
	BNE	XERR
	JSR	ADRSET	;Setup disk read address
	JSR	READ	;Load file
	BNE	XERR	;Check for error

	JMP	UMEM	;Jump to program

CKUN:	CMPI	"U"	;Unload
	BNE	XERR	;Exec. error

	LDAI	2	;File length in sectors.
	JSR	ENTR
	BNE	XERR
	JSR	DPYDSK	;Setup disk write address
	JSR	XTWO	;Until more memory
WIT:	JSR	WRITE	;Write it
	BNE	XERR
	JSR	CLOZE
ECK:	BEQ	XOFF	;Jump if no error
XERR:	LDAI	77	;Print 
	JSR	PCHR
XOFF:	LDAI	0
	STAZ	XU	;Reset XU

RTRN:	PLA
	TAX
	PLA
	TAY
	PLA
	RTI	;Return
DPYDSK:	LDAI	200	;Setup disk buffer address
	STAZ	31	;FLAD+1
	ASLA	;Clear A
	STAZ	FLAD
	LDXI	20	;16 sectors.
XSET:	STXZ	NSEC
	RTS

ADRSET:	LDAI	3	;Setup disk buffer address
	STAZ	FLAD+1
	LDAI	0
	STAZ	FLAD
XTWO:	LDXI	2	;X=2 For two sectors.
	BNE	XSET

   DMARK ← 74	;Directory mark
   FMARK ← 72	;File mark

LOKUP:	JSR	FWAI	;Check if disk busy
	LDAI	364	;Restore track 0
	STA	FDSKC
	JSR	FWAI

	LDAI	375	;Second sector
	STA	FDSKS
	JSR	RBUF	;Load one sector into FBUF
	BNE	NOHED	;Check for read error

	LDAZ	FBUF	;Check for directory mark
	CMPI	DMARK
	BNE	NOHED

	LDXI	17
GDIR:	LDAZX	FBUF	;Save first 16 bytes
	STAZX	DBUF
	DEX
	BPL	GDIR
	LDAZ	SCNT	;Number of sectors in directory
	STAZ	NSEC	;Wipe out NSEC
	LDYI	20	;BLK Length

CKDIR:	LDXI	0

CKNAM:	LDAY	FBUF
	CMPZX	FBLK
	BNE	NXTF

	INY
	INX
	CPXI	12
	BNE	CKNAM
;File names match so..
	LDAY	FBUF	;Get file track number.
	STAZ	FTRK
	LDAY	201	;FBUF+1
	STAZ	FSEC	;File sector number.
	LDAY	202	;FBUF+2
	STAZ	NSEC	;File length.
	TAX
	LDAI	0	;File found.
	RTS

NXTF:	TYA
	ORAI	17
	TAY
	INY		;Get next dir entry
	BPL	CKDIR	;More in buffer

	DECZ	NSEC	;More sectors
	BEQ	FNF

	DEC	FDSKS	;Next sector
	JSR	RBUF
	BNE	NOHED
	LDYI	0
	BEQ	CKDIR

FNF:	LDAI	200	;Not in directory
NOHED:	RTS
OPIN:	JSR	LOKUP	;Lookup file FNAM
	BNE	RX	;File not found

SEEK:	LDAZ	FTRK	;Get track and sector
	STA	FDSKD
	LDAZ	FSEC
	STA	FDSKS
	LDAI	340	;Seek and verify command
	STA	FDSKC

	JSR	FWAI	;Wait and read status
	EORI	177
	ANDI	354	;Flush index bit, etc.

RX:	RTS

;Wait until not busy.
FWAI:	LDA	FDSKC	;Read status
	LSRA
	BCC	FWAI	;Check if busy
	RTS

SETTO:	JSR	FWAI	;Wait until not busy.
SETT:	LDYI	2	;Setup time out interupt vector
	LDAI	PLA
ISET:	STAY	NMIV
	DEY
	BPL	ISET

	LDAI	377	;Init timer
	STA	RTCAH
	STA	RTCAC
	RTS
SETBUF:	LDAI	FBUF	;Read disk into FBUF
	STAZ	FLAD	;Setup buffer pointer.
	ASLA	;Clear A
	STAZ	31	;FLAD+1
	LDXI	1	;X=1 For one sector
	RTS

RBUF:	JSR	SETBUF	;Setup address

;Read sectors from disk.
READ:	JSR	SETTO	;Wait and init time out.
	LDAI	143	;IBM read command (n secs)
	STA	FDSKC

RSEC:	LDYI	0
FLOAD:	LDA	DSKSEL	;Check if byte ready
	BPL	FLOAD
	LDA	FDSKD	;Read byte from disk
	STAIY	FLAD
	INY
	BPL	FLOAD

	LDAZ	FLAD
	EORI	200	;Next sector
	STAZ	FLAD
	BMI	NOPAGE
	INCZ	FLAD+1

NOPAGE:	DEX
	BNE	RSEC	;More sectors

ENDSK:	LDAI	57	;End disk op
	STA	FDSKC
	STX	RTCAC	;Disable timer
	TXA	;Wait for >12 cycles.
	DEX	;X = 377
	TXA
	EOR	FDSKC	;Read disk status
	ANDI	376	;For busy bit
	RTS
;Create file routine
ENTR:	STAZ	FLEN	;Save file length.
	JSR	LOKUP	;Check if file already exists.
	BEQ	FEXIST	;Check if file exists
	CMPI	200	;Not in dir. code
	BEQ	GBLK
FEXIST:	LDAI	377	;Return with error
	RTS

GBLK:	LDAZ	FFSEC	;Get first free sector
	SEC
	SBCZ	FLEN	;Check if it fits on track
	CMPI	345
	BCS	NOBUMP
	DECZ	FFTRK
	LDAI	376
	STAZ	FFSEC
NOBUMP:	LDAZ	FFSEC
	STAZ	FSEC
	LDAZ	FFTRK
	STAZ	FTRK
	JSR	SEEK	;Point to new file
	BNE	FEXIST	;Verify
	LDAI	377	;Set write file open flag.
	STAZ	WFOPEN
	LDAI	0	;Return with no errors
	RTS
WBUF:	JSR	SETBUF	;Write FBUF

WRITE:	JSR	SETTO	;Wait and init timer.

	LDAI	103	;Write multiple sectors command
	STA	FDSKC

CLRY:	LDYI	0
WLOOP:	LDA	DSKSEL	;Wait until empty
	BPL	WLOOP

	LDAIY	FLAD
	STA	FDSKD	;Write chr on disk
	INY
	BPL	WLOOP

QW:	LDA	DSKSEL	;Wait for 129th DRQ
	BPL	QW
	STA	FDSKD

	LDAZ	FLAD
	EORI	200	;Next sector
	STAZ	FLAD
	BMI	CKMOR
	INCZ	FLAD+1
CKMOR:	DEX		;More sectors
	BNE	CLRY

	JSR	ENDSK	;Reset disk, timer. Read status
	BNE	WERR	;Verify if no errors

;Verify disk write
VERIFY:	LDAZ	FSEC	;Reset disk sector number
	STA	FDSKS
	JSR	SETT	;Set timer
	LDXZ	NSEC	;Get number of sectors
	LDAI	147	;Read MS, HE.
	STA	FDSKC

NXTS:	LDYI	0
VWAI:	LDA	DSKSEL	;Wait for byte
	BPL	VWAI
	LDA	FDSKD	;Reset DRQ.
	INY
	BPL	VWAI	;Done with sector

	DEX
	BNE	NXTS	;Done with file

	JSR	ENDSK	;Reset disk, timer. Read status
WERR:	RTS	;Return with error bits
CLOZE:	BITZ	WFOPEN	;Check if file open
	BMI	UPDIR
RERR:	LDAI	377	;Return with error
	RTS

;Update directory
UPDIR:	LDAI	377	;Get end of directory
	STAZ	FTRK
	LDXZ	SCNT	;Get sec.
	INX
	TXA
	EORI	377	;Invert it
	STAZ	FSEC
	STAZ	OSEC	
	JSR	SEEK
	BNE	RERR	;Seek error
	JSR	RBUF	;Read end of directory.
	BNE	RERR	;Read error

	LDAZ	FFTRK	;Point to new file
	STAZ	FTRK
	LDAZ	FFSEC
	STAZ	FSEC

	LDXZ	FFDIR

;BLT FBLK into directory
	LDYI	0
NAMEIT:	LDAY	FBLK
	STAZX	FBUF
	INX
	INY
	CPYI	20	;FBLK Length
	BNE	NAMEIT

	LDXZ	OSEC	;Point to end of directory
	STXZ	FSEC

	STX	FDSKS
	LDXI	1	;For one sector
	STXZ	NSEC
	JSR	WBUF	;Write new file record
	BNE	RERR	;Check for write error

	CLC
	LDAZ	FFDIR
	ADCI	20	;Update end of dir.
	BPL	SVSEC
	LDAI	0
	INCZ	SCNT	;Next sector

SVSEC:	STAZ	FFDIR

	LDAZ	FFSEC
	SEC
	SBCZ	FLEN	;Point to next free sector.
	STAZ	FFSEC
	LDAI	375	;Point to header.
	STAZ	FSEC
	STA	FDSKS	;Start of directory
	JSR	RBUF	;Read directory header
	BNE	RERR	;Check for read error

	LDXI	1
	STXZ	NSEC
	LDXI	17	;Header length
HLOOP:	LDAZX	DBUF	;BLT Header into directory
	STAZX	FBUF
	DEX
	BPL	HLOOP

	JSR	WBUF	;Write directory
	BNE	RERR	;Write error
	STAZ	WFOPEN	;Reset write file open flag

	RTS
;Print a chr. on mem mapped dpy.
PCHR:	JMPIN	PCHRJ
PCHRR:	CMPI	12	;<lf>.
	BEQ	LF
	CMPI	14	;<home> Key on S720 keyboard.
	BNE	CKCR
LF:	CLC
	LDAZ	CUR
	ADCI	100	;Next line
	STAZ	CUR
	BCC	CLIN
	INCZ	23	;CUR+1
	LDAZ	23	;CUR+1
	CMPI	210	;End of DPY mem.
	BNE	CLIN
	LDAI	200
	STAZ	23	;CUR+1
CLIN:	LDYI	77
	LDAI	40
CLOOP:	STAIY	CUR	;Clear line
	DEY
	BPL	CLOOP
	BMI	UPCUR	;Update cursor

CKCR:	CMPI	15	;<cr>
	BNE	CKBS
CR:	LDAZ	CUR
	ANDI	300
	STAZ	CUR
	JMP	UPCUR	;Update cursor

CKBS:	CMPI	10	;<BS>
	BEQ	BS
PIT:	LDYI	0	;Print it.
	STAIY	CUR	;Print chr on screen
	INCZ	CUR
	LDAZ	CUR
	ANDI	77
	BNE	UPCUR	;Update cursor
	DECZ	CUR	;Fix <cr>.
	LDAZ	CUR
	ANDI	300	;<cr>
	STAZ	CUR
	JMP	LF	;New line

BS:	DECZ	CUR	;Back space.
UPCUR:	LDAZ	CUR	;Update cursor
	STA	DCURL
	LDAZ	CURH
	STA	DCURH
	RTS
;Boot strap loader.
BOOTS:	JSR	BWAI	;Wait until not busy.
	LDAI	244	;Step track command
	STA	FDSKC	;Step to track one.
	
	LDAI	100	;Load PCHR
	STAZ	CUR
	LDAI	0
	STAZ	CURH
	LDAI	357	;PCHR sector number + 1.
	STA	FDSKS
	JSR	BOSEC	;Read a sector
	LDAI	0
	STAZ	CUR
	LDAI	2
	STAZ	CURH
	JSR	BOSEC	;IRQV
	LDAI	200
	STAZ	CUR
	JSR	BOSEC
	LDAI	0
	STAZ	CUR
	INCZ	CURH
	JSR	BOSEC
	LDAI	200
	STAZ	CUR
	JSR	BOSEC
	LDAI	0
	STAZ	CUR
	LDAI	374
	STAZ	CURH
	JSR	BOSEC
	LDAI	200
	STAZ	CUR
	JSR	BOSEC
	JMP	FBUF	;Jump to start up routine.
BWAI:	LDA	FDSKC	;Read disk status.
	LSRA	;Get busy bit
	BCC	BWAI
	RTS
BOSEC:	JSR	BWAI
	DEC	FDSKS	;Next sector
	LDYI	0
	LDAI	163	;Read one sector command.
	STA	FDSKC
	JMP	102	;FOR END OF 1K BLOCK.
BOOLO:	LDA	DSKSEL	;Wait for byte from disk.
	BPL	BOOLO
	LDA	FDSKD	;Read byte
	STAIY	CUR
	INY
	BPL	BOOLO
	JSR	BWAI
	EORI	177	;Check for errors
	BNE	WEDGE
	RTS
WEDGE:	JMP	177415	;Error return to ddt.
TERM:	PLA	;Fix stack
	PLA
	PLA
	LDAI	200	;Setup program interrupt enable
	STAZ	UFLG
	ASLA	;Clear A
	STAZ	XU	;Reset exec.
	CLI	;Enable interrutps

ICHR:	JSR	PCHR	;Print a null and then chrs.
TTYIN:	BITZ	UFLG	;Check if program enabled.
	BMI	NOSTOP
	JMP	STOP
NOSTOP:	LDA	ACIAC	;Read ACIA status.
	LSRA	;Get reciver full bit.
	BCC	TTYIN	;Wait for chr.
	LDA	ACIAD	;Get byte from UART

	BEQ	TTYIN	;Flush nulls.
	BNE	ICHR	;Print it.

;TTY mode interrupt routine.
TTYO:	CMPI	14	;<home> to <lf>
	BNE	CKCLR
	LDAI	12
CKCLR:	CMPI	152	;<Clear>
	BNE	CKSB
	LDAI	3	;<CALL>
CKSB:	CMPI	150	;<Send block>
	BNE	NOSLOC
	LDAZ	SHFLOC
	EORI	40	;Complement shift lock bit.
	STAZ	SHFLOC
	JMP	RTRN

NOSLOC:	CMPI	142	;<Type>
	BNE	NOMCOM
	LDAZ	MFLG
	EORI	377	;Complement modem flag
	STAZ	MFLG
	JMP	RTRN

NOMCOM:	STAZ	CHR	;Save it for shifter.
	ANDI	177	;Flush <Repeat> bit.

	CMPI	"A"	;Not less than A
	BCC	NOSHFT
	CMPI	"["	;Less than Z
	BCS	NOSHFT

	LDAZ	SHFLOC	;Get shift lock bit.
	BITZ	CHR	;Check for <Repeat> bit.
	BPL	SHFT
	EORI	40	;Complement shift.
SHFT:	EORZ	CHR	;Shift chr.
	STAZ	CHR

NOSHFT:	LDXZ	CHR
	BITZ	MFLG	;Modem SI/O flag.
	BPL	SHOIT
	CPXI	10	;<bspace>
	BNE	CKDTAB
	LDXI	177
CKDTAB:	CPXI	13	;<dtab>
	BNE	TRANW
	LDXI	33	;<alt>
TRANW:	LDA	ACIAC	;Read SI/O status.
	ANDI	2	;Wait until transmiter empty.
	BEQ	TRANW
	STX	ACIAD	;Transmit it
	JMP	RTRN	;Return from interrupt.

SHOIT:	TXA
	JMP	ECHO	;Print it and return.

   BLOCK 2000	;For a block of zeros.
END